home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-01-16 | 6.9 KB | 307 lines | [TEXT/MACH] |
- \ external code resource linker
- \ to be used for linking in external subroutines
- \ syntax
- \ : <forth word>
- \ [ ExtProc 3 mySub ] ( gets resource PROC "mySub" and links it in )
- \ ( 3 parameters required )
- \ [ ExtFunc 3 myFnc ] ( gets resource FUNC "myFnc" and links it in )
- \ ( 3 parameters required, placeholder for function result )
- \ ;
- \
- \ The external procedure loader follows Pascal calling conventions, i.e.,
- \ it will put one longint per parameter and a return address on top of
- \ the A7 stack. Return is made to the code directly following the loaded
- \ external procedure, just as you would expect.
- \
- \ © 1989 J. Langowski / MacTutor
-
- only forth also mac also assembler
-
- \ Code taken with permission from the Mach2 roundtable on GEnie - JL
- \
- \ An example of writing a new looping structure, ?DO ... NEXT.
- \ Acts like a DO ... LOOP except that the test for loop
- \ completion is done before the loop body is executed, thus
- \ if the ?DO "limit" is less than or equal to the starting "index"
- \ the loop body will be skipped (remember that a DO ... LOOP will
- \ always execute the loop body at least once, even if the starting
- \ index equals the limit). Waymen @ PASC
-
- ASCII ?DO_ CONSTANT ?DOMark
-
- : ?DO ( limit index -- ) \ compile time ( -- )
- STATE @
- IF
- $26C526C6 , ( MOVE.L D5,(A3)+
- MOVE.L D6,(A3)+ )
- $2C1E2A1E , ( MOVE.L (A6)+,D6
- MOVE.L (A6)+,D5 )
- $6000 W, ( BRA )
- HERE >R 0 W, \ space for forward branch offset
- ?DOMark >R \ compiler flag
- ELSE
- -1 ABORT" Compile only!"
- THEN ; IMMEDIATE
-
- : NEXT ( -- )
- \ compile time ( -- )
- STATE @ IF
- R> ?DOMark = IF
- $5286 W, ( ADDQ.L #1,D6)
- HERE R@ - R@ W! \ patch forward branch left by ?DO
- $BA86 W, ( CMP.L D6,D5 )
- R> HERE - \ backward branch offset for BGT
- $6E00 W, W, ( BGT )
- $2C232A23 , ( MOVE.L -(A3),D6
- MOVE.L -(A3),D5 )
- ELSE
- -1 ABORT" Unpaired ?DO"
- THEN
- ELSE
- -1 ABORT" Compile only!"
- THEN ; IMMEDIATE
-
- \ ------------------------------------------
- \ external procedure linker code starts here
- \ ------------------------------------------
-
- $20 constant bl
- variable subrfile
-
- : pushA6 $2F1E w, ;
- : push0 $2F3C w, 0 , ;
- : popA6 $2D1F w, ;
- : pushret $41FA0000 , \ LEA 0(PC),A0
- $2F08 w, \ MOVE.L A0,-(A7)
- here 4- \ address of PC reference
- ;
-
- : ExtProc { | procHdl retAddr -- }
- bl word number? IF ( # params OK )
- 0 ?DO pushA6 NEXT
- pushret
- ascii PROC bl word call GetNamedResource
- ?dup IF -> procHdl
- procHdl @ here procHdl call SizeRsrc
- dup allot ( procPtr here size )
- cmove \ move code into Forth object space
- here over - swap w! \ resolve LEA reference
- ELSE abort" ExtProc - can't find routine"
- THEN
- ELSE abort" ExtProc - parameter number syntax error"
- THEN
- ;
-
- : ExtFunc { | procHdl retAddr -- }
- bl word number? IF ( # params OK )
- push0 \ space for function result
- 0 ?DO pushA6 NEXT
- pushret
- ascii FUNC bl word call GetNamedResource
- ?dup IF -> procHdl
- procHdl @ here procHdl call SizeRsrc
- dup allot ( procPtr here size )
- cmove \ move code into Forth object space
- here over - swap w! \ resolve LEA reference
- popA6
- ELSE abort" ExtProc - can't find routine"
- THEN
- ELSE abort" ExtProc - parameter number syntax error"
- THEN
- ;
-
- \ --------------------------------------------------
- \ define some calls to external (Fortran) procedures
- \ --------------------------------------------------
-
- " machsub" call openresfile subrfile !
-
- : x2r [ extproc 2 x2r ] ;
- : r2x [ extproc 2 r2x ] ;
-
- : distance ( p q r | -- )
- [ extproc 3 distance ]
- ;
-
- variable myarrayH
- variable myarraysize
-
- : makearray ( arrayhandle arraysize -- )
- [ extproc 2 makearray ]
- ;
-
- : gaussj ( a n np b m mp ierr -- )
- [ extproc 7 gaussj ]
- ;
-
- : matmul ( a b c n np m mp l lp -- )
- [ extproc 9 matmul ]
- ;
-
- subrfile @ call closeresfile
-
- \ --------------------------------------------------
- \ end of external definitions; testing routines
- \ --------------------------------------------------
-
- also sane fp
- fvariable x 20 vallot
- fvariable y 20 vallot
- fvariable dist
-
- : f>s { | [ 6 lallot ] x s -- }
- ^ x f! \ store from FP stack into local variable
- ^ x ^ s x2r
- s
- ;
-
- : s>f { s | [ 6 lallot ] x -- }
- ^ s ^ x r2x
- ^ x f@ \ push local variable to FP stack
- ;
-
- : setup.x.y
- 1.5 x f! 2.5 x 10 + f! 3.5 x 20 + f!
- 3.5 y f! -1.0 y 10 + f! 0.0 y 20 + f!
- ;
-
- : compute.distance
- x y dist distance
- cr ." The distance between points x and y is "
- dist f@ f. ." units" cr
- ;
-
- : test.array
- cr ." Setting up 10000 element array..." cr
- 10000 myarraySize !
- myarrayH myarraySize makearray
- ." Testing setup: " cr
- 10000 0 DO
- ." array(" i . ." ) = " myarrayH @ @ i 4* + @ . cr
- 1000 +loop
- myarrayH @ call disposhandle drop
- ;
-
- 5 constant maxdim
-
- variable n variable n1
- variable m variable m1
- variable ierr
-
- variable a maxdim dup * 4* 4- vallot ( np*np real array )
- variable b maxdim 4* 4- vallot ( np el. real vector )
- variable c maxdim dup * 4* 4- vallot ( np*np real array )
- variable d maxdim 4* 4- vallot ( np el. real vector )
-
- : setup.vars
- maxdim n1 ! 1 m1 ! ;
-
- : read.str ( -- addr )
- pad 1+ 80 expect span @ pad c! pad ;
-
- : num.inp.err
- ." numeric input error, reenter - "
- ;
-
- : num.lim.err
- ." number outside limits, reenter - "
- ;
-
- : read.int
- begin read.str cr number? not while drop
- num.inp.err
- repeat
- ;
-
- : read.real
- begin read.str cr fnumber? not while fdrop
- num.inp.err
- repeat
- ;
-
- : read.int.limit { lo hi -- }
- begin
- read.int dup lo > over hi < and
- not while drop
- num.lim.err
- repeat
- ;
-
- : read.real.limit ( flo fhi -- )
- begin
- fover fover
- read.real
- fswap fover f> fswap fover f< and
- not while fdrop
- num.lim.err
- repeat
- fswap fdrop fswap fdrop
- ;
-
- : dumpAB { dim | -- }
- dim 0 do
- cr dim 0 do
- i 5 * j + 4* a + @ s>f f.
- loop
- i 4* b + @ s>f f.
- loop
- ;
-
- : dumpC { dim | -- }
- dim 0 do
- cr dim 0 do
- i 5 * j + 4* c + @ s>f f.
- loop
- loop
- ;
-
- : gausstest { | dim -- }
- cr
- setup.vars
- ." Enter problem dimension (min=1,max=10) : "
- 0 n1 @ read.int.limit -> dim
- dim 0 do
- cr ." Enter row # " i . ." - "
- dim 0 do read.real f>s
- i 5 * j + 4* a + ! \ store in array a
- loop
- read.real f>s i 4* b + ! \ store right-hand side
- loop
- a c 400 cmove \ copy a to c
-
- cr ." Calling GAUSSJ..."
- dim n ! 1 m !
- a n n1 b m m1 ierr gaussj
- cr ." After GAUSSJ. Components of A,B:"
- dim dumpAB
- cr ." Checking solution. Old A:" dim dumpC
-
- c b d n n1 n n1 m m1 matmul
- cr ." Old B: "
- dim 0 do
- i 4* d + @ s>f f.
- loop
- cr
- ;
-
- NEW.WINDOW lineq
- " Linear Equations" lineq TITLE
- 50 50 300 450 lineq BOUNDS
- Document Visible NoCloseBox GrowBox lineq ITEMS
-
- 600 5000 terminal gauss
-
- : go.gauss activate fp 7 fixed gausstest
- begin ?terminal until
- bye
- ;
-
- : start
- lineq add
- lineq gauss build
- lineq dup call selectwindow call setport
- gauss go.gauss
- ;
-
-
-